/*************************************************************
 * Title: AccessContext.java
 * Description: 
 * Author: Huang Shaobin
 * Email: shaobin.software@gmail.com
 * CreateTime: Feb 21, 2013 6:07:38 PM
 ************************************************************/
package snow.core.context;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;

/**
 *
 */
@SuppressWarnings("serial")
public class AccessContext implements Serializable {

	private static final ThreadLocal<AccessContext> current = new ThreadLocal<AccessContext>();

	public static AccessContext getCurrent() {
		AccessContext context = current.get();
		if (context == null) {
			context = new AccessContext();
			current.set(context);
		}
		return context;
	}

	public static void removeCurrent() {
		current.remove();
	}

	private Map<String, Object> container;

	private AccessContext() {
		container = new HashMap<String, Object>();
	}

	public void clear() {
		if (container != null) {
			container.clear();
		}
	}

	protected <T> T get(String key, Class<T> targetClass) {
		final Object value = container.get(key);
		if (targetClass != null && targetClass.isInstance(value)) {
			return targetClass.cast(value);
		}
		return null;
	}

	public <T> T getFromSession(String key, Class<T> targetClass) {
		return get("session_" + key, targetClass);
	}

	public List<Locale> getLocalesFromRequest() {
		List<?> list = this.get("locales", List.class);
		List<Locale> locales = Collections.emptyList();
		if (CollectionUtils.isNotEmpty(list)) {
			locales = new ArrayList<Locale>(list.size());
			for (final Object item : list) {
				if (item instanceof Locale) {
					locales.add((Locale) item);
				}
			}
		}
		return locales;
	}

	protected void put(String key, Object value) {
		container.put(key, value);
	}

	public void putFromRequest(String key, Object value) {
		put("request_" + key, value);
	}

	public void putFromRequestAttribute(String key, Object value) {
		putFromRequest("attribute_" + key, value);
	}

	public void putFromRequestHeader(String key, Object value) {
		putFromRequest("header_" + key, value);
	}

	public void putFromRequestLocales(List<Locale> locales) {
		putFromRequest("locales", locales);
	}

	public void putFromResponse(String key, Object value) {
		put("response_" + key, value);
	}

	public void putFromSession(String key, Object value) {
		put("session_" + key, value);
	}

	public void remove(String key) {
		container.remove(key);
	}

	public void removeFromSession(String key) {
		remove("session_" + key);
	}

}
